## ROM ROM is 8KB in size, mapped at the top of the address space (0fe000h). It may be mirrored elsewhere - need to investigate once machine is booting. ## RAM The RAM is mapped at the start of the address space to accommodate the IVT (there being no way to relocate it prior to the '286). Some parts of the BIOS set up a stack near the top of the address space. An example from the diagnostic prompt loop at ROM offset 13e9h): mov ax, 0E0FAh mov ss, ax mov sp, 5Eh ; Results in top of stack at 0e0ffeh call sub_FF065 ; Some code in here reads from memory above top of ; stack, e.g. ss:5fh Is this just video RAM being used by early init BIOS code? Positive offsets from 0e0fah: 5fh (95) Init to 0 in bootstrap Bit 3 must be zero before OutputCharacterTeletype will proceed. Bit 3 cleared after waiting for port 56h, bit 1 to become set Bit 2 if set causes OutputCharacterTeletype to wait on port 42h then output character to port 40h followed by writing 3 and 2 to port 46h 5eh (94) Top of stack after initial memory scan Updated by sub_fed18 (latest keyboard input?) 50h (80) Top of stack before initial memory scan (no calls, interrupts?) ### RAM scan Early in the boot process the BIOS scans through memory looking for a word that cannot have 0aaaah written, be rotated right once, and reads back as 05555h. The scan covers the first 512KB of address space (this matches the advertised specification of 128KB user memory, expandable to 512KB). Once found, the paragraph of the failing word is stored at 0:02beh. ### Low memory usage 0000:0100 - 0000:02b9 copied from BIOS ROM at 16cbh on startup; contains data plus error messages (maybe offset tables?) 0000:02be word Paragraph of highest usable memory word ## Boot Drive Prompt, Monitor, and Diagnostics When prompted for the boot drive name, A or B followed by a carriage return are accepted but you can also enter M or T. Any other response is treated as 'A'. M loads the resident monitor. A seven-entry jump table at ROM offset 1ba4h has the handlers for top-level commands. T loads the diagnostics. ## Monitor Monitor entry point is at ROM offset 10d4h. Also at offset 0h there is a far jump into the monitor input loop, skipping the code that clears the screen and prints the monitor version banner. Command parsing is very simple; any deviation from what is expected will cause the prompt "?" to appear, and the parser is reset. Where a space is expected, the code allows multiple spaces (but not tabs or newlines). All numeric input is in hexadecimal; leading zeroes may be omitted. The following commands are accepted; parameters are G aaaa:bbbb Function 4: "Goto" (DS:SI) Jumps to DS:SI M aaaa:bbbb,cccc:dddd,eeee Function 5: "Move Bytes" (DS:SI,ES:DI,CX) Copies CX bytes from [DS:SI] to [ES:DI] with verification. Mismatched values are reported on screen. P aaaa P aaaa,bbbb Function 6: "Port Byte I/O" If one argument provided, reads from I/O port and displays the value. If two arguments provided, writes value to I/O port. S aaaa:bbbb Function 7: "Store Bytes" (DS:SI) Repeatedly outputs DS:SI and [DS:SI], then inputs an 8-bit number. The value is written to [DS:SI] and read back; mismatches are reported on screen. SI is incremented after each loop. Enter '.' to quit. WC Function 1: Something to do with memory comparision? WD aaaa:bbbb,cccc Function 2: "Display Words" (DS:SI,CX) Displays the CX words at [DS:SI] on screen. WF aaaa:bbbb,cccc,dddd Function 3: "Fill Words" (DS:SI,CX,BX) Fills CX words at [DS:SI] with the value of BX, with verification. Mismatched values are reported on screen. WM As M but word-sized WP As P but word-sized WS As S but word-sized Note: monitor functions 1, 2 and 3 are not available in byte format even though the code supports this option. cmd plain Wprefix C ff 00 D ff 02 E ff ff F ff 04 G 09 ff H ff ff I ff ff J ff ff K ff ff L ff ff M 09 08 N ff ff O ff ff P 0b 0a Q ff ff R ff ff S 0d 0c ## Diagnostics Diagnostic entry point is at ROM offset 13d5h. The diagnostic input loop expects a 1 or 2 char code followed by a carriage return (this indicates which test to run). The mapping of codes to test routines are stored in BIOS ROM at offset 143F. Valid codes are: C Console (CRT) FA Floppy A FB Floppy B HA hard disk? HB hard disk? IF Floppy interrupt IT Timer interrupt M0 Memory, 64KB M1 Memory, 256KB M2 Memory, 384KB M3 Memory, 512KB ### Test IF This test checks the floppy interrupt. It installs a handler for interrupt 22h that modifies AX. ### Test IT This test checks the timer interrupt. It installs a handler for interrupt 20h that modifies AX, then loops 30000 times waiting for AX to change. If it isn't modified in time then an error message is displayed: TIMER INTERRUPT ERROR ### Tests M0, M1, M2, M3 These tests check the system (non-video) memory. All four memory tests perform the same actions; they differ only in the amount of memory they check. The test algorithm is: ; Test each word can be read/written for each word in memory: write 0aaaah rotate right by 1 bit delay (equivalent of push/pop) compare word to 5555h if not equal, display error ; Test write/read with long delay if all words passed test: delay (1770h loops) for each word in memory: rotate right by 1 bit delay (1770h loops) for each word in memory: compare word to 0aaaah if not equal, display error A failure in the first half of the test results in a message like this: MEMORY FAILURE xxxx:yyyy abcd_efgh_ijkl_mnop which indicates a failure at offset yyyy in segment xxxx. a-p will be 0 for bits which passed the test and 1 for bits which failed. ## Video Text mode screen buffer starts at 0e0000h. Default fill is 0e020h (ASCII space). Font data is stored in video RAM at 0e4000h. A routine at ROM offset 1093h populates this. The first 32 characters are set to all blanks by a loop at ROM offset 10a3h; the remaining 96 are copied from BIOS ROM offset 05h. The font data is expanded as it is copied; each character takes up 32 bytes in video RAM but only the first 16 are stored in ROM. The remaining 16 bytes are set to all zero (is this spare space in case the CRTC is reprogrammed for larger character sizes, or just some strange memory mapping?) The font mapping is: Value Character 00 Blank 01 ! Exclamation mark 02 " Double quote 03 # Hash 04 $ Dollar symbol 05 % Percent symbol 06 & Ampersand 07 ' Single quote 08 ( Left paren 09 ) Right paren 0a * Asterisk 0b + Plus 0c , Comma 0d - Hyphen 0e . Full stop 0f / Forward slash 10-19 0-9 1a : Colon 1b ; Semicolon 1c < Left angle 1d = Equals 1e > Right angle 1f ? Question mark 20 @ At-symbol 21-3a A-Z 3b [ Left bracket 3b \ Backslash 3c ] Right bracket 3d ^ Caret 3e _ Underscore 3f ` Backtick 40-5a a-z 5b { Left brace 5c ¦ Broken pipe 5d } Right brace 5e ~ Tilde 5f 50% grey 60+ Graphical characters to make the Olympia People logo CRTC initial register settings are stored in BIOS ROM at offset 18B3h as a 16-entry array of (register, value) pairs. Initial values are: reg value Notes 0 69h (105) Horiz total (screen width in chars) 1 50h (80) Horiz displayed (chars displayed) 2 58h (88) Horiz sync position (in chars) 3 5ah (90) H and V sync width (in chars, upper nibble is H, lower is V, 0 may mean 16) 4 1ah (26) Vert total (screen height in chars) 5 09h (9) Vert total adjust (in scanlines) 6 19h (25) Vert displayed (lines displayed) 7 1ah (26) Vert sync position (vsync start in chars) 8 00h (0) Interlace and skew (0=none) 9 12h (18) Max raster address 10 60h (96) Cursor start raster (raster 0, blink, fast) 11 12h (18) Cursor end raster (raster 18) 12 00h (0) Display start address high 13 00h (0) Display start address low 14 00h (0) Cursor address high 15 00h (0) Cursor address low Note: no entries for registers 16/17 (light pen address high/low) as they are read-only. port 6ch (6845 CRTC register select?): write -> sets register available in port 6eh port 6eh (6845 CRTC register data?) ## Interrupts Two 8259A (or compatible) programmable interrupt controllers are present with their ports mapped as: Port Purpose 14h Slave command port 16h Slave data port 18h Master command port 1ah Master data port The BIOS initializes the PICs early on (code at ROM offset 0a40hh) with the following command words: Port Value Purpose -- -- -- Master 18h 11h ICW1 (init PIC, edge-triggerd, cascaded, ICW4 to follow) 1ah 20h ICW2 (IVT base offset; 20h is the first interrupt not reserved by Intel) 1ah 80h ICW3 (slave PIC connected to interrupt request 7; equivalent to IRQ 27h) 1ah 03h ICW4 (80x86 mode, automatic EOI on last interrupt acknowledge pulse) 1ah ffh DATA (disable all interrupts) -- -- -- Slave 14h 11h ICW1 (init PIC, same as master) 16h 28h ICW2 (IVT base offset; 28h is the first interrupt after the master PIC) 16h 07h ICW3 (interrupt request 7 on master) 16h 03h ICW4 (same as master) 16h ffh DATA (disable all interrupts) From looking at the diagnostic tests, it appears that the non-reserved IRQs are allocated as: IRQ Purpose -- -- 20h Timer 22h Floppy controller? ## Misc port 16h: on entering diagnostics, write 0ffh port 18h (8259A-compatible PIC, command port): at startup (ROM offset 0a40h), write 11h (init PIC, edge-triggered, cascade-mode, IC4 to follow) on entering test IF, write 0ah, read, then AND with 4 port 1ah (8259A-compatible PIC, data port): on entering diagnostics, write 0ffh on entering test IT, read, turn off bit 0, write back on leaving test IT, read, turn on bit 0, write back on entering test IF, read, turn off bit 2, write back on leaving test IF, read, turn on bit 2, write back port 7ch: at startup: write 84, delay 8c0h LOOPs, write 4h after 28h failures waiting for port 56h to return bit 0 set, write 80h and dynamic halt on entering test IT, turn on bit 0, toggle bit 3, turn off all others After loading data from the boot disk, the boot code is called with: CS = ES = Base paragraph of boot sector IP = 0 DX = Segment address of top of system RAM CL = Boot drive (0-based) CH = SS:5fh AND 2 (flag?)